package com.example.edu.file;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

/**
 * 文件匹配后缀匹配
 */
public class FileMatchingVisitor
        extends SimpleFileVisitor<Path> {

    /**
     * 匹配器
     */
    private final PathMatcher matcher;


    /**
     * 匹配的文件数量
     */
    private int numMatches = 0;

    public FileMatchingVisitor(String pattern) {
        this.matcher = FileSystems.getDefault()
                .getPathMatcher("glob:" + pattern); // 使用 glob 模式创建匹配器
    }

    /**
     * 使用比较器进行匹配 文件或则目录的名称
     *
     * @param file
     */
    public void find(Path file) {
        Path name = file.getFileName();
        if (name != null && matcher.matches(name)) {
            numMatches++;
            System.out.println("scan file " + file);
        }
    }

    /**
     * 打印匹配到的总个数
     */
    public void done() {
        System.out.println("Matched " + numMatches + " files");
    }

    /**
     * 访问文件时，使用匹配模式过滤文件
     *
     * @param file  永远都是文件
     * @param attrs
     * @return
     */
    @Override
    public FileVisitResult visitFile(Path file,
                                     BasicFileAttributes attrs) {
        if (file.toFile().isHidden()) {
            return FileVisitResult.SKIP_SUBTREE;
        }
        find(file);
        return FileVisitResult.CONTINUE;
    }

    /**
     * 访问文件夹
     *
     * @param dir   永远都是文件夹
     * @param attrs
     * @return
     */
    @Override
    public FileVisitResult preVisitDirectory(Path dir,
                                             BasicFileAttributes attrs) {
        if (dir.toFile().isHidden()) {
            return FileVisitResult.SKIP_SUBTREE;
        }

        System.out.println("scan folder " + dir);

        return FileVisitResult.CONTINUE;
    }

    /**
     * 访问文件失败时 打印错误信息
     *
     * @param file
     * @param exc
     * @return
     */
    @Override
    public FileVisitResult visitFileFailed(Path file,
                                           IOException exc) {
        System.err.println(exc);
        return FileVisitResult.CONTINUE;
    }
}
